package org.example.Interceptor;

import org.example.domain.Payload;
import org.example.domain.Permission;
import org.example.domain.UserDto;
import org.example.exception.GlobleException;
import org.example.utils.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

import static org.example.constant.Constants.REDIS_ACCESS_TOKEN;

// 1. 定义权限拦截器
@Component
public class PermissionInterceptor implements HandlerInterceptor {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 获取Authorization头
        String authHeader = request.getHeader("Authorization");

// 同时判断：头不存在（null）或值为空（包括空白字符）
        if (authHeader == null || authHeader.trim().isEmpty()) {
            response.sendError(401, "未登录（缺少认证信息）");
            return false; // 终止后续处理，必须添加
        }
        Payload payload = JwtUtil.parseJwtToken(authHeader);
        UserDto logininfo = payload.getLogininfo();
        List<Permission> userPermissions = payload.getPermissions();

        // 4. 从Redis中获取该用户的有效Token
        String redisTokenKey = String.format(REDIS_ACCESS_TOKEN,logininfo.getId()); // Redis键格式
        String redisStoredToken = (String) redisTemplate.opsForValue().get(redisTokenKey);

        // 5. 比对前端Token与Redis中的Token是否一致
        if (StringUtils.isEmpty(redisStoredToken) || !Objects.equals(authHeader, redisStoredToken)) {
            response.sendError(401, "Token已失效（可能已登出或被踢下线）");
            return false;
        }

        // 提取请求URL和方法
        String requestUrl = request.getRequestURI();
        String requestMethod = request.getMethod();

        boolean hasPermission = false;
        for (Permission perm : userPermissions){
            if(requestMethod.equalsIgnoreCase(perm.getMethod()) &&
            matchUrlTemplate(perm.getUrl(), requestUrl)){
                hasPermission = true;
                break;
            }
        }
//        // 校验是否匹配权限
//        boolean hasPermission = userPermissions.stream().anyMatch(perm ->
//            // 方法匹配 + URL模板匹配
//            requestMethod.equalsIgnoreCase(perm.getMethod()) &&
//            matchUrlTemplate(perm.getUrl(), requestUrl)
//        );

        if (!hasPermission) {
            throw  new GlobleException("无权限访问");
        }
        return true;
    }
    /**
     * 匹配 URL 模板与实际请求 URL
     * @param template 权限中定义的 URL 模板（如 /users/{id}）
     * @param actualUrl 实际请求的 URL（如 /users/123）
     * @return 是否匹配
     */
    private boolean matchUrlTemplate(String template, String actualUrl) {
        // 处理 null 情况（理论上 template 和 actualUrl 不应为 null，保险处理）
        if (template == null || actualUrl == null) {
            return false;
        }

        // 去除前后空格，避免意外空格导致匹配失败
        template = template.trim();
        actualUrl = actualUrl.trim();

        // 分割模板和实际 URL 为路径片段（按 "/" 分割，过滤空字符串）
        String[] templateSegments = splitUrl(template);
        String[] actualSegments = splitUrl(actualUrl);

        // 路径片段数量不同，直接不匹配（如 /users/{id} 和 /users 长度不同）
        if (templateSegments.length != actualSegments.length) {
            return false;
        }

        // 逐个比对路径片段
        for (int i = 0; i < templateSegments.length; i++) {
            String templateSeg = templateSegments[i];
            String actualSeg = actualSegments[i];

            // 模板片段是动态参数（如 {id}、{userId}），直接跳过比对
            if (isDynamicSegment(templateSeg)) {
                continue;
            }

            // 固定片段必须完全相等（如 "users" 必须匹配 "users"）
            if (!templateSeg.equals(actualSeg)) {
                return false;
            }
        }

        // 所有片段匹配
        return true;
    }

    /**
     * 分割 URL 为路径片段（按 "/" 分割，过滤空字符串）
     * 例："/users/{id}/edit" → ["users", "{id}", "edit"]
     */
    private String[] splitUrl(String url) {
        // 按 "/" 分割，同时过滤空字符串（处理开头/结尾的 "/" 导致的空片段）
        return Arrays.stream(url.split("/"))
                .filter(segment -> !segment.isEmpty())
                .toArray(String[]::new);
    }

    /**
     * 判断模板片段是否为动态参数（如 {id}、{userId}）
     */
    private boolean isDynamicSegment(String segment) {
        // 动态参数格式：以 { 开头，以 } 结尾
        return segment.startsWith("{") && segment.endsWith("}");
    }



}

